<?php


class WSB_Model_SimpleTree
{

	/**
	 * @var array
	 */
	private $_tree = array();

	/**
	 * @var string
	 */
	protected $_modelClass = null;

	/**
	 * @var string
	 */
	protected $_collectionClass = null;

	/**
	 * @var string
	 */
	protected $_key = null;

	/**
	 * @var string
	 */
	protected $_parentKey = null;

	/**
	 * @var integer
	 */
	private $_idPointer = null;

	/**
	 * @var integer
	 */
	private $_pidPointer = null;

	/**
	 * @param array $rows
	 * @return void
	 */
	public function __construct(array $rows)
	{
		$this->init();
		foreach($rows AS $row) {
			$id = $row[$this->_key];
			$pid = $row[$this->_parentKey];
			$this->_tree[$pid][$id] = $row;
		}
	}

	/**
	 * @return void
	 */
	public function init()
	{}

	/**
	 * @return integer
	 */
	public function getId()
	{
		return $this->_idPointer;
	}

	/**
	 * @return integer
	 */
	public function getParentId()
	{
		return $this->_pidPointer;
	}

	/**
	 * @return boolean
	 */
	public function hasParent()
	{
		if(empty($this->_pidPointer)) {
			return false;
		}
		foreach($this->_tree AS $pid=>$node) {
			if($pid != $this->_pidPointer) {
				return array_key_exists($this->_pidPointer, $node);
			}
		}
		return false;
	}

	/**
	 * @return Sherpa_Model_CategoryTree
	 */
	public function getParent()
	{
		if($this->hasParent()) {
			foreach($this->_tree AS $pid=>$node) {
				if($pid != $this->_pidPointer) {
					if(array_key_exists($this->_pidPointer, $node)) {
						$this->_idPointer = $node[$this->_pidPointer][$this->_key];
						$this->_pidPointer = $node[$this->_pidPointer][$this->_parentKey];
						return $this;
					}
				}
			}
		}
		return null;
	}

	/**
	 * @return boolean
	 */
	public function hasChildren()
	{
		return array_key_exists($this->_idPointer, $this->_tree);
	}

	/**
	 * @return array Array aus Sherpa_Model_CategoryTree
	 */
	public function getChildren()
	{
		$nodes = array();
		if($this->hasChildren()) {
			foreach($this->_tree[$this->_idPointer] AS $node) {
				$this->_idPointer = $node[$this->_key];
				$this->_pidPointer = $node[$this->_parentKey];
				$nodes[] = clone($this);
			}
		}
		return $nodes;
	}

	/**
	 * @param integer $nodeId
	 * @return Sherpa_Model_CategoryTree
	 */
	public function getNode($nodeId)
	{
		foreach($this->_tree AS $pid=>$branch) {
			foreach($branch AS $id=>$leave) {
				if($id == $nodeId) {
					$this->_idPointer = $id;
					$this->_pidPointer = $pid;
					return $this;
				}
			}
		}
		return null;
	}

	/**
	 * @return Sherpa_Model_Categories
	 */
	public function getRootline()
	{
		$data = array();
		if(!$this->isRoot()) {
			$tree = clone($this);
			$data[] = $tree->getData();
			$i=0;
			while($tree->hasParent()) {
				$i++;
				if($i >= 100) die('ENDLOS-Schleife');
				$tree = $tree->getParent();
				$data[] = $tree->getData();
			}
		}
		return new $this->_collectionClass($data);
	}

	/**
	 * @return boolean
	 */
	public function isRoot()
	{
		return empty($this->_idPointer) && empty($this->_pidPointer);
	}

	/**
	 * @param string $key
	 * @return mixed
	 */
	public function get($key)
	{
		if($this->isRoot()) {
			return '';
		}
		return $this->_tree[$this->_pidPointer][$this->_idPointer][$key];
	}

	/**
	 * @return Sherpa_Model_Category
	 */
	public function getModel()
	{
		if($this->isRoot()) {
			return null;
		}
		return new $this->_modelClass($this->getData());
	}

	/**
	 * @return array
	 */
	public function getData()
	{
		if($this->isRoot()) {
			return null;
		}
		return $this->_tree[$this->_pidPointer][$this->_idPointer];
	}

	/**
	 * @return void
	 */
	public function debug()
	{
		$hasParent = intval($this->hasParent());
		$hasChildren = intval($this->hasChildren());
		echo "
			PID = {$this->_pidPointer}<br />
			ID = {$this->_idPointer}<br />
			PARENT = {$hasParent}<br />
			CHILDREN = {$hasChildren}<br />
		";
	}

}